using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using System.IO;

namespace WikipediaSurfaceBrowser
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {
        ApplicationSettings _settings = new ApplicationSettings();        
        Dictionary<string, string[]> _knownTags = new Dictionary<string, string[]>();
        Search _search = null;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public SurfaceWindow1()
        {
            InitializeComponent();

            // Add handlers for Application activation events
            AddActivationHandlers();
        }

        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here
        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }

        private void SurfaceWindow_Loaded(object sender, RoutedEventArgs e)
        {            
            WikiToXaml.WikiToXamlConvertor.RenderForSurface = true;            

            foreach (string topic in _settings.StartupTopics.Split(new char[] {';'}))
            {
                AddWikiTopic(topic);
            }

            foreach (string image in _settings.StartupImages.Split(new char[] { ';' }))
            {
                AddImagePad(image);
            }

            if (_settings.ShowSearch)
            {
                _search = new Search(this.mainScatterView);
                this.mainScatterView.Items.Add(new ScatterViewItem()
                {
                    Content = _search,
                    CanScale = false                    
                });
            }

            Uri uri = new Uri("/Resources/tags.txt", UriKind.Relative);
            System.Windows.Resources.StreamResourceInfo info = Application.GetContentStream(uri);
            StreamReader sr = new StreamReader(info.Stream);
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                if (line.Trim().Length < 5)
                {
                    return;
                }

                _knownTags.Add(line.Substring(0, 2), line.Substring(3).Split(new char[] { ';' }));
            }
        }

        private void AddImagePad(string image)
        {            
            this.mainScatterView.Items.Add(new ScatterViewItem()
            {
                Content = new ImagePad() { Source = image },
                Width = _settings.ImageWidth,
                Height = _settings.ImageHeight
            });
        }

        private void SurfaceWindow_ContactEnter(object sender, ContactEventArgs e)
        {
            if (e.Contact.IsTagRecognized && (e.Contact.Tag.Type == TagType.Byte))
            {
                ReadByTag(e.Contact.Tag.Byte.Value);
            }
        }

        private void ReadByTag(byte? tag)
        {            
            if (!tag.HasValue)
            {
                return;
            }

            string tagValue = String.Format("{0:X2}", tag);

            if (_knownTags.ContainsKey(tagValue))
            {
                List<string> loadedTopics = new List<string>();
                foreach (ScatterViewItem svi in mainScatterView.Items)
                {
                    if (svi.Content.GetType() != typeof(WikiTopic))
                    {
                        continue;
                    }
                    loadedTopics.Add(((WikiTopic)svi.Content).Topic);
                    loadedTopics.Add(((WikiTopic)svi.Content).RedirectFromTopic);
                }
                foreach (string topic in _knownTags[tagValue])
                {
                    if (loadedTopics.Contains(topic))
                    {
                        continue;
                    }

                    AddWikiTopic(topic);
                }
            }

            string imageLibraryFolder = _settings.ImageLibraryFolder + System.IO.Path.DirectorySeparatorChar + tagValue;

            if (Directory.Exists(imageLibraryFolder))
            {
                List<string> loadedImages = new List<string>();

                foreach (ScatterViewItem svi in mainScatterView.Items)
                {
                    if (svi.Content.GetType() != typeof(ImagePad))
                    {
                        continue;
                    }

                    loadedImages.Add(((ImagePad)svi.Content).LocalSource);
                }

                foreach (string image in Directory.GetFiles(imageLibraryFolder))
                {
                    if (loadedImages.Contains(image))
                    {
                        continue;
                    }
                    this.mainScatterView.Items.Add(new ScatterViewItem()
                    {
                        Content = new ImagePad() { LocalSource = image }                        
                    });
                }
            }
        }

        private void AddWikiTopic(string topic)
        {
            string l = _settings.StartupLanguage;
            if (_search != null)
            {
                l = _search.WikiLanguage;
            }

            this.mainScatterView.Items.Add(new ScatterViewItem()
            {
                Width = _settings.TopicWidth,
                Height = _settings.TopicHeight,
                CanScale = false,
                Content = new WikiTopic(l)
                {
                    Topic = Uri.EscapeUriString(topic)
                }
            });
        }
    }
}